package com.mac.hosp_pre.admin.listener;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mac.hosp_pre.admin.model.resp.DictExcelDto;
import com.mac.hosp_pre.admin.service.DictService;
import com.mac.hosp_pre.admin.entity.Dict;
import com.mac.hosp_pre.admin.model.resp.ExcErrorInfoDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;

@Slf4j
public class DictExcelListener implements ReadListener<DictExcelDto> {

    private int batchCount;

    //缓存对象，达到最大数量，需要存库，清空缓存
    private List<Dict> cachedDataList = ListUtils.newArrayListWithExpectedSize(batchCount);

    private DictService dictService;

    private List<ExcErrorInfoDto> errorInfoDtos;

    public DictExcelListener(int batchCount,DictService dictService, List<ExcErrorInfoDto> errorInfoDtos) {
        this.dictService = dictService;
        this.errorInfoDtos = errorInfoDtos;
        this.batchCount = batchCount;
    }


    @Override
    public void invoke(DictExcelDto dictExcelDto, AnalysisContext analysisContext) {
        int i = 0;
        if (!StringUtils.hasText(dictExcelDto.getDictCode())){
            errorInfoDtos.add(new ExcErrorInfoDto("dictCode","字典编码不能为空"));
            i++;
        }else{
            long count = dictService.count(new LambdaQueryWrapper<Dict>()
                    .eq(Dict::getDictCode, dictExcelDto.getDictCode()));
            if (count > 0){
                errorInfoDtos.add(new ExcErrorInfoDto("dictCode","dictCode:["+dictExcelDto.getDictCode()+"]已经存在，请使用其他编码"));
                i++;
            }
        }
        if (!StringUtils.hasText(dictExcelDto.getName())){
            errorInfoDtos.add(new ExcErrorInfoDto("name","字典名称不能为空"));
            i++;
        }
        if (!StringUtils.hasText(dictExcelDto.getVal())){
            errorInfoDtos.add(new ExcErrorInfoDto("val","字典值不能为空"));
            i++;
        }
        if (StringUtils.hasText(dictExcelDto.getParentCode())){
            Dict one = dictService.getOne(new LambdaQueryWrapper<Dict>()
                    .eq(Dict::getDictCode, dictExcelDto.getDictCode()));
            if (one == null){
                errorInfoDtos.add(new ExcErrorInfoDto("parentCode","父级编码:["+dictExcelDto.getParentCode()+"]不存在，请先添加父级编码"));
                i++;
            }else {
                dictExcelDto.setParentId(one.getId());
            }
        }
        if (i == 0){
            Dict entity = new Dict();
            BeanUtils.copyProperties(dictExcelDto,entity);
            cachedDataList.add(entity);
            if (cachedDataList.size() >= batchCount){
                dictService.saveBatch(cachedDataList,batchCount);
                // 存储完成清理 list
                cachedDataList = ListUtils.newArrayListWithExpectedSize(batchCount);
            }
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (CollectionUtil.isNotEmpty(cachedDataList)){
            cachedDataList = null;
        }
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        log.error("字典导入错误：{}",exception);
        Map<Integer, Head> headMap = context.currentReadHolder().excelReadHeadProperty().getHeadMap();
        if (CollectionUtil.isNotEmpty(headMap)){
            Head head = headMap.get(context.currentReadHolder().excelReadHeadProperty().getHeadRowNumber());
            if (head != null){
                errorInfoDtos.add(new ExcErrorInfoDto(head.getFieldName(),head.getHeadNameList().get(0)+"错误:"+exception.getMessage()));
            }
        }

    }
}
